﻿#define _CRT_SECURE_NO_WARNINGS 1
#include"ConcurrentAlloc.h"
#include"Common.h"

//ntimes 一轮申请的次数  nworks 线程数 ，round 轮
void BenchmarkMalloc(size_t ntimes, size_t nworks, size_t rounds) {
    std::vector<std::thread> vthread(nworks);
    std::atomic<size_t> malloc_costtime = 0;
    std::atomic<size_t> free_costtime = 0;
    for (size_t k = 0; k < nworks; ++k) {
        vthread[k] = std::thread([&, k]() {
            std::vector<void*> v;
            v.reserve(ntimes);
            for (size_t j = 0; j < rounds; ++j) {
                auto begin1 = std::chrono::high_resolution_clock::now();
                for (size_t i = 0; i < ntimes; i++) {
                   // void* ptr = malloc((16 + i) % 8192 + 1);
                    void* ptr = malloc(16);
                    if (ptr == nullptr) {
                        // 处理内存分配失败
                        std::cerr << "Malloc failed" << std::endl;
                        return;
                    }
                    v.push_back(ptr);
                }
                auto end1 = std::chrono::high_resolution_clock::now();
                auto begin2 = std::chrono::high_resolution_clock::now();
                for (size_t i = 0; i < ntimes; i++) {
                    free(v[i]);
                }
                auto end2 = std::chrono::high_resolution_clock::now();
                v.clear();
                auto duration1 = std::chrono::duration_cast<std::chrono::milliseconds>(end1 - begin1).count();
                auto duration2 = std::chrono::duration_cast<std::chrono::milliseconds>(end2 - begin2).count();
                malloc_costtime += duration1;
                free_costtime += duration2;
            }
            });
    }
    for (auto& t : vthread) {
        t.join();
    }
    std::cout << nworks << "个线程并发执行" << rounds << "轮次，每轮次malloc " << ntimes << "次: 花费：" << malloc_costtime << " ms" << std::endl;
    std::cout << nworks << "个线程并发执行" << rounds << "轮次，每轮次free " << ntimes << "次: 花费：" << free_costtime << " ms" << std::endl;
    std::cout << nworks << "个线程并发malloc&free " << nworks * rounds * ntimes << "次，总计花费：" << malloc_costtime + free_costtime << " ms" << std::endl;
}

void BenchmarkConcurrentMalloc(size_t ntimes, size_t nworks, size_t rounds) {
    std::vector<std::thread> vthread(nworks);
    std::atomic<size_t> malloc_costtime = 0;
    std::atomic<size_t> free_costtime = 0;
    for (size_t k = 0; k < nworks; ++k) {
        vthread[k] = std::thread([&]() {
            std::vector<void*> v;
            v.reserve(ntimes);
            for (size_t j = 0; j < rounds; ++j) {
                auto begin1 = std::chrono::high_resolution_clock::now();
                for (size_t i = 0; i < ntimes; i++) {
                    void* ptr = ConcurrentAlloc(16);
                    //void* ptr = ConcurrentAlloc((16 + i) % 8192 + 1);


                    if (ptr == nullptr) {
                        // 处理内存分配失败
                        std::cerr << "ConcurrentAlloc failed" << std::endl;
                        return;
                    }
                    v.push_back(ptr);
                }
                auto end1 = std::chrono::high_resolution_clock::now();
                auto begin2 = std::chrono::high_resolution_clock::now();
                for (size_t i = 0; i < ntimes; i++) {
                    ConcurrentFree(v[i]);
                }
                auto end2 = std::chrono::high_resolution_clock::now();
                v.clear();
                auto duration1 = std::chrono::duration_cast<std::chrono::milliseconds>(end1 - begin1).count();
                auto duration2 = std::chrono::duration_cast<std::chrono::milliseconds>(end2 - begin2).count();
                malloc_costtime += duration1;
                free_costtime += duration2;
            }
            });
    }
    for (auto& t : vthread) {
        t.join();
    }
    std::cout << nworks << "个线程并发执行" << rounds << "轮次，每轮次concurrent alloc " << ntimes << "次: 花费：" << malloc_costtime << " ms" << std::endl;
    std::cout << nworks << "个线程并发执行" << rounds << "轮次，每轮次concurrent dealloc " << ntimes << "次: 花费：" << free_costtime << " ms" << std::endl;
    std::cout << nworks << "个线程并发concurrent alloc&dealloc " << nworks * rounds * ntimes << "次，总计花费：" << malloc_costtime + free_costtime << " ms" << std::endl;
}

int main() {
    size_t n = 10000;
    std::cout << "==========================================================" << std::endl;
    BenchmarkConcurrentMalloc(n, 4, 10);
    std::cout << std::endl << std::endl;
    BenchmarkMalloc(n, 4, 10);
    std::cout << "==========================================================" << std::endl;
    return 0;
}